package cn.le.netty.cient;

import cn.le.bean.enums.EnumMsgCode;
import cn.le.bean.vo.NettyMsg;
import cn.le.bean.vo.NettyServerAddressVO;
import cn.le.netty.RedisUtils;
import cn.le.netty.util.ConnectionUtil;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * netty 客户端,发送消息
 */
public final class NettyClient {

    /**
     * 发送点对点消息
     * @param msg
     */
    public static void sendPoint(NettyMsg msg){
        //1.查询redis,消息接受者netty链接的是那台机器
        NettyServerAddressVO vo = RedisUtils.NettyUtils.getConnect(String.valueOf(msg.getTid()));
        if (vo == null){
            //转离线消息
            return;
        }
        send(msg,vo.getIp(),vo.getPort());
    }

    /**
     * 消息群发
     * @param msg
     * @return
     */
    public static void sendGroup(NettyMsg msg){
        //1.查询群对应的消息人数
        List<NettyServerAddressVO> groupMap = RedisUtils.ImUserUtils.getGroup(String.valueOf(msg.getTid()));
        if (CollectionUtils.isEmpty(groupMap)){
            //离线处理
            return ;
        }
        groupMap.forEach(vo->{
            if (vo.getId() == msg.getFid()){//排除发送者自己
                return;
            }
            NettyMsg bean = msg.clone(msg);
            bean.setTid(vo.getId());//注入链接id
            bean.setCode(EnumMsgCode.point_send.getCode());
            send(bean,vo.getIp(),vo.getPort());
        });
    }

    /**
     * 登录netty 服务器
     * @param ip
     * @param port
     * @param id
     */
    public static void login(String ip,int port,int id) {
        NettyMsg msg = new NettyMsg();
        msg.setCode(EnumMsgCode.login.getCode());
        msg.setFid(id);
        send(msg,ip,port);
    }
    /**
     * 消息发送
     * @param msg
     * @param ip
     * @param port
     * @return
     */
    private static void send(NettyMsg msg,String ip,int port) {
        ChannelHandlerContext ctx = ConnectionUtil.get(ip,port);
        if (ctx == null){
            onConnection(ip,port);
        }
        //自旋,等待连接建立成功
        while (ctx == null){
            ctx = ConnectionUtil.get(ip,port);
        }
        //发送消息
        ctx.channel().writeAndFlush(msg);
    }
    private static void onConnection(String ip,int port){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Client.connection(ip,port);
            }
        }).start();
    }
}
